home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Especial Multimedia
/
Especial Multimedia.iso
/
Multimed
/
Fuentes
/
T1UTILS1.ZIP
/
T1BINARY.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-09-14
|
7KB
|
278 lines
/* t1binary
*
* This program takes an Adobe Type-1 font program in ASCII (PFA) format and
* converts it to binary (PFB) format.
*
* Copyright (c) 1992 by I. Lee Hetherington, all rights reserved.
*
* Permission is hereby granted to use, modify, and distribute this program
* for any purpose provided this copyright notice and the one below remain
* intact.
*
* I. Lee Hetherington (ilh@lcs.mit.edu)
*
* $Log: t1binary.c,v $
* Revision 1.1 92/05/22 11:58:17 ilh
* initial version
*
* Ported to Microsoft C/C++ Compiler and MS-DOS operating system by
* Kai-Uwe Herbing (herbing@netmbx.netmbx.de) on June 12, 1992. Code
* specific to the MS-DOS version is encapsulated with #ifdef _MSDOS
* ... #endif, where _MSDOS is an identifier, which is automatically
* defined, if you compile with the Microsoft C/C++ Compiler.
*
*/
#ifndef lint
static char rcsid[] =
"@(#) $Id: t1binary.c,v 1.1 92/05/22 11:58:17 ilh Exp Locker: ilh $";
static char copyright[] =
"@(#) Copyright (c) 1992 by I. Lee Hetherington, all rights reserved.";
#ifdef _MSDOS
static char portnotice[] =
"@(#) Ported to MS-DOS by Kai-Uwe Herbing (herbing@netmbx.netmbx.de).";
#endif
#endif
/* Note: this is ANSI C. */
#ifdef _MSDOS
#include <fcntl.h>
#include <getopt.h>
#include <io.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
/* int32 must be at least 32-bit */
#if INT_MAX >= 0x7FFFFFFFUL
typedef int int32;
#else
typedef long int32;
#endif
#define LINESIZE 256
#define MAXBLOCKLEN ((1L<<17)-6)
#define MINBLOCKLEN ((1L<<8)-6)
#define MARKER 128
#define ASCII 1
#define BINARY 2
#define DONE 3
typedef unsigned char byte;
static FILE *ifp = stdin;
static FILE *ofp = stdout;
static char line[LINESIZE];
/* for PFB block buffering */
static byte blockbuf[MAXBLOCKLEN];
static int32 blocklen = MAXBLOCKLEN;
static int32 blockpos = -1;
static int blocktyp = ASCII;
/* This function flushes a buffered PFB block. */
static void output_block()
{
int32 i;
/* output four-byte block length */
fputc((int) (blockpos & 0xff), ofp);
fputc((int) ((blockpos >> 8) & 0xff), ofp);
fputc((int) ((blockpos >> 16) & 0xff), ofp);
fputc((int) ((blockpos >> 24) & 0xff), ofp);
/* output block data */
for (i = 0; i < blockpos; i++)
fputc(blockbuf[i], ofp);
/* mark block buffer empty and uninitialized */
blockpos = -1;
}
/* This function outputs a single byte. If output is in PFB format then output
is buffered through blockbuf[]. If output is in PFA format, then output
will be hexadecimal if in_eexec is set, ASCII otherwise. */
static void output_byte(byte b)
{
if (blockpos < 0) {
fputc(MARKER, ofp);
fputc(blocktyp, ofp);
blockpos = 0;
}
blockbuf[blockpos++] = b;
if (blockpos == blocklen)
output_block();
}
/* This function outputs a null-terminated string through the PFB buffering. */
static void output_string(char *string)
{
while (*string)
output_byte((byte) *string++);
}
/* This function returns the value (0-15) of a single hex digit. It returns
0 for an invalid hex digit. */
static int hexval(char c)
{
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
else if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
else if (c >= '0' && c <= '9')
return c - '0';
else
return 0;
}
/* This function outputs the binary data associated with a string of
hexadecimal digits. There must be an even number of digits. */
static void output_hex_string(char *string)
{
while (string[0] && string[0] != '\n') {
if (!string[1]) {
fprintf(stderr, "error: only one hex digit\n");
exit(1);
}
output_byte((byte)((hexval(string[0]) << 4) + hexval(string[1])));
string += 2;
}
}
/* This function returns 1 if the string contains all '0's. */
static int all_zeroes(char *string)
{
while (*string == '0')
string++;
return *string == '\0' || *string == '\n';
}
static void usage()
{
fprintf(stderr,
"usage: t1binary [-l block-length] [input [output]]\n");
fprintf(stderr,
"The block length applies to the length of blocks in the\n");
fprintf(stderr,
"PFB output file; the default is to use the largest possible.\n");
exit(1);
}
static void print_banner()
{
static char rcs_revision[] = "$Revision: 1.1 $";
static char revision[20];
if (sscanf(rcs_revision, "$Revision: %19s", revision) != 1)
revision[0] = '\0';
fprintf(stderr, "This is t1binary %s.\n", revision);
}
int main(int argc, char **argv)
{
int c;
extern char *optarg;
extern int optind;
extern int getopt(int argc, char **argv, char *optstring);
print_banner();
/* interpret command line arguments using getopt */
while ((c = getopt(argc, argv, "l:")) != -1)
switch (c) {
case 'l':
blocklen = atoi(optarg);
if (blocklen < MINBLOCKLEN) {
blocklen = MINBLOCKLEN;
fprintf(stderr,
"warning: using minimum block length of %d\n",
blocklen);
} else if (blocklen > MAXBLOCKLEN) {
blocklen = MAXBLOCKLEN;
fprintf(stderr,
"warning: using maximum block length of %d\n",
blocklen);
}
break;
default:
usage();
break;
}
if (argc - optind > 2)
usage();
/* possibly open input & output files */
if (argc - optind >= 1) {
ifp = fopen(argv[optind], "r");
if (!ifp) {
fprintf(stderr, "error: cannot open %s for reading\n",
argv[optind]);
exit(1);
}
}
if (argc - optind >= 2) {
ofp = fopen(argv[optind + 1], "w");
if (!ofp) {
fprintf(stderr, "error: cannot open %s for writing\n",
argv[optind + 1]);
exit(1);
}
}
#ifdef _MSDOS
/* As we are processing a PFB (binary) output */
/* file, we must set its file mode to binary. */
_setmode(_fileno(ofp), _O_BINARY);
#endif
/* peek at first byte to see if it is the PFB marker 0x80 */
c = fgetc(ifp);
if (c == MARKER) {
fprintf(stderr,
"error: input may already be binary (starts with 0x80)\n");
exit(1);
}
ungetc(c, ifp);
/* Finally, we loop until no more input. We need to look for `currentfile
eexec' to start eexec section (hex to binary conversion) and line of all
zeros to switch back to ASCII. */
while (fgets(line, LINESIZE, ifp), !feof(ifp) && !ferror(ifp)) {
if (blocktyp == ASCII && strcmp(line, "currentfile eexec\n") == 0) {
output_string(line);
output_block();
blocktyp = BINARY;
} else if (blocktyp == BINARY && all_zeroes(line)) {
output_block();
blocktyp = ASCII;
output_string(line);
} else if (blocktyp == ASCII) {
output_string(line);
} else {
output_hex_string(line);
}
}
output_block();
fputc(MARKER, ofp);
fputc(DONE, ofp);
fclose(ifp);
fclose(ofp);
return 0;
}